package com.data4.gateway.filter;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.data4.feignapi.common.constants.GatewayConstants;
import com.data4.feignapi.common.constants.SupplierConstants;
import com.data4.feignapi.common.constants.UserConstants;
import com.data4.feignapi.config.JwtUtils;
import com.data4.feignapi.vo.SupplierVO;
import com.data4.feignapi.vo.UserVO;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Resource
    private JwtUtils jwtUtils;

    // 排除路径
    private static final List<String> EXCLUDED_PATHS = Arrays.asList(
            "/user/login", "/user/register", "/supplier/login",
            "/util", "/supplier/register", "/product/getProduct",
            "/user/getProductDetail"
    );

    @Override
    public Mono<Void> filter(@NotNull ServerWebExchange exchange,
                             @NotNull GatewayFilterChain chain) {
        String path = exchange.getRequest().getURI().getPath();
        // 判断是否是排除路径
        if (isExcludedPath(path)) {
            System.err.println(path);
            return chain.filter(exchange); // 不拦截，直接放行
        }

        HttpHeaders headers = exchange.getRequest().getHeaders();
        String authHeader = headers.getFirst(UserConstants.USER_TOKEN_HEADER);

        // 验证并解析Token
        Claims claims = jwtUtils.validateAndParseToken(authHeader);
        System.err.println(claims);
        if (BeanUtil.isEmpty(claims)) {
            // Token无效，返回401
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();
        }
        // 解析成功，设置解析内容到请求头
        Map<String, Object> claimsMap = claims;
        //设置请求头
        setRequestHeader(exchange, claims, claimsMap);

        return chain.filter(exchange);
    }


    private void setRequestHeader(@NotNull ServerWebExchange exchange, Claims claims, @NotNull Map<String, Object> claimsMap) {
        if (CollUtil.contains(claimsMap.keySet(), UserConstants.USER_TOKEN_PREFIX)) {
            UserVO userVO = BeanUtil.toBean(claims
                    .get(UserConstants.USER_TOKEN_PREFIX), UserVO.class);
            System.err.println("userVO:" + userVO);
            exchange.getRequest().mutate()
                    .header(GatewayConstants.X_USER_ID, userVO.getUserId().toString())
                    .header(GatewayConstants.X_USER_NAME, userVO.getUserName())
                    .build();
        } else {
            SupplierVO supplierVO = BeanUtil.toBean(claims
                    .get(SupplierConstants.USER_TOKEN_PREFIX), SupplierVO.class);
            System.err.println("supplierVO:" + supplierVO);
            exchange.getRequest().mutate()
                    .header(GatewayConstants.X_SUPPLIER_ID, supplierVO
                            .getSupplierId().toString())
                    .header(GatewayConstants.X_BOSS_NAME, supplierVO.getBoosName())
                    .build();
        }
    }

    // 判断路径是否需要排除
    private boolean isExcludedPath(@NotNull String path) {
        return EXCLUDED_PATHS.stream()
                .anyMatch(excludedPath -> path.matches(excludedPath + ".*"));
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE; // 确保过滤器优先执行
    }
}
